package javax.generic.swing;

import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

import javax.generic.persistance.AbstractPersistableEntity;
import javax.generic.persistance.GenericDao;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import org.apache.log4j.Logger;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainWin extends JFrame {

	private static final long serialVersionUID = 5441319298567787700L;

	private static final Logger LOG = Logger.getLogger(MainWin.class);

	private static Dialog master = new JDialog();

	private JMenu akcijaMenu = new JMenu("Akcije");

	private List<String> usedMenmonics = new ArrayList<String>();

	public static ClassPathXmlApplicationContext CTX;

	public static MainWin createWindowAndContext() {
		LOG.info("loading spring context");
		CTX = new ClassPathXmlApplicationContext(new String[] { "META-INF/spring/applicationContext.xml" });
		LOG.info("spring context loaded");
		MainWin frame = new MainWin();
		AbstractForm.dao = CTX.getBean(GenericDao.class);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		return frame;
	}

	public MainWin() {
		super();

		setExtendedState(Frame.MAXIMIZED_BOTH);
		setTitle("Glavna forma");
		// setSize(300, 300);

		int width = Toolkit.getDefaultToolkit().getScreenSize().width;
		int height = Toolkit.getDefaultToolkit().getScreenSize().height;
		setBounds(0, 0, width, height);

		JMenu fileMenu = new JMenu("Fajl");
		fileMenu.setMnemonic('a');
		fileMenu.add(createMenuItem("Kraj rada", 'k', new ExitActionListener(), "remove"));

		akcijaMenu.setMnemonic('k');

		JMenu aboutMenu = new JMenu("O Programu");
		aboutMenu.setMnemonic('m');
		aboutMenu.add(createMenuItem("O Programu", 'm', new AboutAction(), null));

		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		menuBar.add(fileMenu);
		menuBar.add(akcijaMenu);
		menuBar.add(aboutMenu);
	}

	private JMenuItem createActionMenuItem(String label, final Class<? extends AbstractForm<? extends AbstractPersistableEntity>> formClazz, String icon) {
		LOG.debug("creating menu item: " + label);
		ActionListener listener = new NamedActionListener() {

			AbstractForm<? extends AbstractPersistableEntity> instance = null;

			@Override
			public void actionPerformed(ActionEvent event) {
				LOG.debug("click on menu");
				try {

					if (instance == null) {
						LOG.debug("creating constructor for " + formClazz.getSimpleName());
						Constructor<? extends AbstractForm<? extends AbstractPersistableEntity>> constructor = formClazz.getConstructor(Dialog.class, Boolean.class);

						LOG.debug("invoking constructor for " + formClazz.getSimpleName());
						instance = constructor.newInstance(master, false);
					}
					nameAndShowPanel(instance);
				} catch (Exception e) {
					LOG.error(e);
				}
			}
		};

		JMenuItem item = new JMenuItem(label);
		if (icon != null) {
			item.setIcon(new ImageIcon(getClass().getResource("/images/" + icon + ".gif")));
		}

		String m = label.toUpperCase().substring(0, 1);
		for (int i = 1; i < label.length(); i++) {

			if (usedMenmonics.contains(m) || !m.matches("[A-Za-z]")) {
				m = label.toUpperCase().substring(i, i + 1);
			} else if (m.matches("[A-Za-z]")) {
				usedMenmonics.add(m);
				break;
			}
		}

		item.setMnemonic(m.charAt(0));
		item.addActionListener(listener);
		if (listener instanceof NamedActionListener) {
			((NamedActionListener)listener).setName(label);
		}
		return item;
	}

	private JMenuItem createMenuItem(String label, char mnemonic, ActionListener listener, String icon) {
		JMenuItem item = new JMenuItem(label);
		if (icon != null) {
			item.setIcon(new ImageIcon(getClass().getResource("/images/" + icon + ".gif")));
		}

		item.setMnemonic(mnemonic);
		item.addActionListener(listener);
		if (listener instanceof NamedActionListener) {
			((NamedActionListener)listener).setName(label);
		}
		return item;
	}

	private class AboutAction extends NamedActionListener {

		@Override
		public void actionPerformed(ActionEvent event) {
			// JOptionPane.showMessageDialog(master, "Projekt realizovao Milan",
			// "O programu", JOptionPane.INFORMATION_MESSAGE);
		}
	}

	private class ExitActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent event) {
			System.exit(0);
		}
	}

	public void addItemToActionMenu(String title, Class<? extends AbstractForm<? extends AbstractPersistableEntity>> clazz, String icon) {
		akcijaMenu.add(createActionMenuItem(title, clazz, icon));
	}

	public void addItemToActionMenu(String title, Class<? extends AbstractForm<? extends AbstractPersistableEntity>> clazz) {
		akcijaMenu.add(createActionMenuItem(title, clazz, null));
	}

	public void addSeparatorItem() {
		akcijaMenu.addSeparator();
	}

}
